# -*- coding: utf-8 -*-
# Copyright (c) 2011, Wojciech Bederski (wuub.net)
# All rights reserved.
# See LICENSE.txt for details.
import os
import re
from . import subprocess_repl

# PowerShell in interactive mode shows no prompt, so we must hold it by hand.
# Every command prepended with other command, which will output only one character ('.')
# When user command leads to no output (for example, 'cd ..'), we get only this character,
# and then we send command to show prompt explicitly.
# No output at all means, that PowerShell needs more input (multiline mode).
# In this case we proceeds sending user input without modifications.

class PowershellRepl(subprocess_repl.SubprocessRepl):
    TYPE = "powershell"
    PREPENDER = b"."

    def __init__(self, encoding, **kwds):
        if not encoding:
            # Detect encoding
            chcp = os.popen('chcp')
            chcp_encoding = re.match(r'[^\d]+(\d+)', chcp.read())
            if not chcp_encoding:
                raise LookupError("Can't detect encoding from chcp")
            encoding = "cp" + chcp_encoding.groups()[0]
            print(encoding)

        super(PowershellRepl, self).__init__(encoding, **kwds)

        # Using this to detect whether PowerShell returns some output or it needs more input
        # PowerShell in interactive mode doesn't show prompt, so we must hold it by hand
        # It's a hack and, for example, we can send 'Write-Host "" -NoNewLine' with no output, but in outhr cases it may work well
        self.got_output = True
        self.multiline = False

        self.prompt()

    def read_bytes(self):
        # this is windows specific problem, that you cannot tell if there
        # are more bytes ready, so we read only 1 at a times

        result = super(PowershellRepl, self).read_bytes()

        # Consumes output (it must be equal to PREPENDER)
        if result and not self.got_output:
            self.got_output = True
            self.multiline = False
            self.prompt()
            # Don't return PREPENDER, read another input
            return self.read_bytes()

        return result

    def write_bytes(self, bytes):
        # Drop flag on new input
        self.got_output = False
        if not self.multiline:
            # Turn multiline mode on, it will be turned off, when PowerShell returns some output
            self.multiline = True
            self.prepend()
        self.do_write(bytes)

    def do_write(self, bytes):
        super(PowershellRepl, self).write_bytes(bytes)

    def prompt(self):
        """ Sends command to get prompt """
        self.do_write(b'Write-Host ("PS " + (gl).Path + "> ") -NoNewline\n')

    def prepend(self):
        """ Command to prepend every output with special mark to detect multiline mode """
        self.do_write(b'Write-Host "' + PowershellRepl.PREPENDER + b'" -NoNewLine; ')
